#include "Anx_uart.h"

#include "usart.h"

/* Private includes ----------------------------------------------------------*/
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "stdarg.h"

#include "Anx_RTT.h"

/* Private define ------------------------------------------------------------*/

/* Private typedef ------------------------------------------------------------*/


/* Extern variables ---------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_usart1_rx;


/* Private variables ---------------------------------------------------------*/
RAM_D1 char uart_rx_buffer[USART_RX_BUFFER_MAX] = { 0 };
// char uart_rx_buffer[USART_RX_BUFFER_MAX] = { 0 };
static char uart_tx_buffer[USART_TX_BUFFER_MAX];
static uint16_t uart_rx_index = 0;


#if (SUPPORT_RTOS == 1)
static osMailQDef(uart_rx_mail, 4, char*);
static osMailQId  uart_rx_mail;
static osThreadId uart_rx_handle;
#else
static char uart_rx_flag = 0;    // 接收完成标志
#endif

const static char TAG[] = "UART";

/* Public variables ---------------------------------------------------------*/


/* Private functions ---------------------------------------------------------*/




#if (SUPPORT_RTOS == 1)
/**
 * @brief 串口接收数据处理函数
 *
 * @note 对接收到的数据进行处理
 *
 * @param argument: 邮箱id
 *
 */
RAM_ITCM void Anx_UartRx_Task(void const* argument)
{
    osMailQId* mail = (osMailQId*)argument;
    osEvent evt;
    char* str;

    Debug_log(TAG, "rx task start");
    while (1)
    {
        // vTaskDelay(pdMS_TO_TICKS(100));
        evt = osMailGet(*mail, osWaitForever);        // wait for mail
        if (evt.status == osEventMail)
        {
            // Debug_log(TAG,"get mail");
            /**********   处理接收到的邮件   **********/
            str = evt.value.p;
            Debug_log(TAG, "len:%d", uart_rx_index);
            Debug_log(TAG, "%s", str);

            /**********   处理接收到的邮件   **********/
            Debug_log(TAG, "Processing completed");
            memset(str, 0, USART_RX_BUFFER_MAX);    // 清空邮件内容
        }
    }
}

/**
 * @brief 串口回调函数
 *
 * @note 该函数需要完成调用，stm32f4xx_it.c
 *       接收数据完成后，用于通知其他任务进行处理
 *
 * @param huart: 串口实例
 *
 */
void Anx_UART_Rx_Callback(UART_HandleTypeDef* huart)
{
    if ((__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET))	    // 获得串口空闲中断标志
    {
        __HAL_UART_CLEAR_IDLEFLAG(huart);	// 清除空闲中断标志
        HAL_UART_DMAStop(huart);	                        // 停止DMA传输，防止数据覆盖

        uart_rx_index = USART_RX_BUFFER_MAX - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);     // 计算实际接收的数据长度


        if (uart_rx_index > 0)
        {
            uart_rx_buffer[uart_rx_index] = '\0';                              // 在接收数据的末尾添加字符串结束符（适用于ASCII数据）
            osMailPut(uart_rx_mail, &uart_rx_buffer);
        }

        // memset(uart_rx_buffer,0,sizeof(uart_rx_buffer));                 // 清空接收缓冲区
        HAL_UART_Receive_DMA(huart, (uint8_t*)uart_rx_buffer, USART_RX_BUFFER_MAX);       // 重新开启DMA，准备接收下一帧数据。
    }
}

void HAL_UART_ErrorCallback(UART_HandleTypeDef* huart)
{
    if (huart->Instance == USART1)
    {
        Debug_log(TAG, "UART error");
    }
}


/**
 * @brief 串口接收不定长功能初始化
 *
 * @note 开启DMA接受及空闲中断
 *
 * @param huart: 串口实例
 * @param buf: DMA接收存储
 * @param buf_len: 存储器长度
 *
 */
void Anx_Uart_Init(UART_HandleTypeDef* huart)
{
    Debug_log(TAG, "init start");


    // HAL_UART_Receive_IT(huart, (uint8_t*)uart_rx_buffer, USART_RX_BUFFER_MAX);
    // //__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
    __HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);
    HAL_UART_Receive_DMA(huart, (uint8_t*)uart_rx_buffer, USART_RX_BUFFER_MAX);
    // HAL_UART_Receive_IT(huart, (uint8_t*)uart_rx_buffer, USART_RX_BUFFER_MAX);

    uart_rx_mail = osMailCreate(osMailQ(uart_rx_mail), NULL);

    osThreadDef(uart_rx_task, Anx_UartRx_Task, osPriorityNormal, osPriorityNormal, 128);//广播任务
    uart_rx_handle = osThreadCreate(osThread(uart_rx_task), &uart_rx_mail);
    //osThreadCreate(osThread(uart_rx_task), &uart_rx_mail);

    Debug_log(TAG, "init completed");
}



/**
 * @brief 串口发送函数
 *
 * @note 允许使用可变参数
 *
 * @param huart: 串口实例
 * @param data: 发送的字符串
 *
 */
void Anx_UART_SendData(UART_HandleTypeDef* huart, char* data, ...)
{
    int len;

    va_list ap;
    va_start(ap, data);
    vsprintf(uart_tx_buffer, data, ap);
    va_end(ap);

    len = strlen(uart_tx_buffer);

    taskENTER_CRITICAL();
    HAL_UART_Transmit(huart, (uint8_t*)uart_tx_buffer, len, 20);
    taskEXIT_CRITICAL();
}
#else

/**
 * @brief 串口接收数据处理函数
 *
 * @note 对接收到的数据进行处理
 *
 * @param argument: 邮箱id
 *
 */
void Anx_UartRx_Task(void const* argument)
{
    if (uart_rx_flag == 0)
        return;

    uart_rx_flag = 0;
    Debug_log(TAG, "len:%d\r\n", uart_rx_index);
    Debug_log(TAG, "%s\r\n", uart_rx_buffer);


    Anx_Rx_Process(uart_rx_buffer, uart_rx_index);

    /**********   处理接收到的邮件   **********/
    Debug_log(TAG, "Processing completed\r\n");
    memset(uart_rx_buffer, 0, USART_RX_BUFFER_MAX);    // 清空邮件内容
}

/**
 * @brief 串口回调函数
 *
 * @note 该函数需要完成调用，stm32f4xx_it.c
 *       接收数据完成后，用于通知其他任务进行处理
 *
 * @param huart: 串口实例
 *
 */
void Anx_UART_Rx_Callback(UART_HandleTypeDef* huart)
{
    if ((__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET))	    // 获得串口空闲中断标志
    {
        __HAL_UART_CLEAR_IDLEFLAG(huart);	// 清除空闲中断标志
        HAL_UART_DMAStop(huart);	                        // 停止DMA传输，防止数据覆盖

        uart_rx_index = USART_RX_BUFFER_MAX - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);     // 计算实际接收的数据长度


        if (uart_rx_index > 0)
        {
            uart_rx_buffer[uart_rx_index] = '\0';                              // 在接收数据的末尾添加字符串结束符（适用于ASCII数据）
            uart_rx_flag = 1;
        }

        // memset(uart_rx_buffer,0,sizeof(uart_rx_buffer));                 // 清空接收缓冲区
        HAL_UART_Receive_DMA(huart, (uint8_t*)uart_rx_buffer, USART_RX_BUFFER_MAX);       // 重新开启DMA，准备接收下一帧数据。
    }
}

void HAL_UART_ErrorCallback(UART_HandleTypeDef* huart)
{
    if (huart->Instance == USART1)
    {
        Debug_err(TAG, "UART error\r\n");
    }
}


/**
 * @brief 串口接收不定长功能初始化
 *
 * @note 开启DMA接受及空闲中断
 *
 * @param huart: 串口实例
 * @param buf: DMA接收存储
 * @param buf_len: 存储器长度
 *
 */
void Anx_Uart_Init(UART_HandleTypeDef* huart)
{
    Debug_log(TAG, "init start\r\n");


    // HAL_UART_Receive_IT(huart, (uint8_t*)uart_rx_buffer, USART_RX_BUFFER_MAX);
    // //__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
    __HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);
    HAL_UART_Receive_DMA(huart, (uint8_t*)uart_rx_buffer, USART_RX_BUFFER_MAX);
    // HAL_UART_Receive_IT(huart, (uint8_t*)uart_rx_buffer, USART_RX_BUFFER_MAX);

    memset(uart_rx_buffer, 0, USART_RX_BUFFER_MAX);
    //osThreadCreate(osThread(uart_rx_task), &uart_rx_mail);

    Debug_log(TAG, "init completed\r\n");
}



/**
 * @brief 串口发送函数
 *
 * @note 允许使用可变参数
 *
 * @param huart: 串口实例
 * @param data: 发送的字符串
 *
 */
void Anx_UART_SendData(UART_HandleTypeDef* huart, char* data, ...)
{
    int len;

    va_list ap;
    va_start(ap, data);
    vsprintf(uart_tx_buffer, data, ap);
    va_end(ap);

    len = strlen(uart_tx_buffer);

    HAL_UART_Transmit(huart, (uint8_t*)uart_tx_buffer, len, 20);
}


#endif

/**
 * @brief 串口数据比较函数
 *
 * @note 用于比较接收到的字符串命令
 *
 * @param buf: 目标命令
 * @param desc: 接收数据
 *
 */
char Anx_Uart_Strcmp(char* buf, char* desc)
{
    if (strcmp(buf, desc) == 0)
        return true;
    return false;
}

__weak void Anx_Rx_Process(char* data, uint16_t len)
{
    // 该函数用于用户重定义
}